<template>
  <div>
    <a-tabs
      v-model="projectType"
      class="project-content"
      :style="{ height: `${height - 140}px` }"
      default-active-key="创建"
      @change="handleTabChange"
    >
      <a-tab-pane key="创建" tab="我创建的">
        <!-- 卡片模式 -->
        <div
          v-show="isCard"
          id="projects"
          class="projects projects-card"
          :style="{ 'max-height': `${height - 216}px` }"
        >
          <!-- 新建项目 用户引导 step-6 -->
          <guide-step-popover :guide-step="6">
            <template #header>
              <div
                class="card"
                :style="{ 'margin-left': margin }"
                @click="setAddProjectVisible"
              >
                <a-icon-font type="iconjiahao" class="add-icon" />
                <br />
                <span class="add-project">新建项目</span>
              </div>
            </template>
          </guide-step-popover>

          <!-- 所有项目 卡片  -->
          <template v-for="(project, index) in projectsCard">
            <!-- 第一个 项目卡片 新用户引导 step-7 -->
            <guide-step-popover
              v-if="index === 0"
              :key="project.id"
              :guide-step="7"
            >
              <template #header>
                <span :style="{ 'margin-left': margin }">
                  <router-link :to="`/project/${project.id}`" tag="div">
                    <project-card
                      :project="project"
                      :role="1"
                      :page-size="pageSizeInCard"
                      @copyProject="copyProject(project)"
                      @setVisible="setVisible(project)"
                      @deleteProject="deleteProject"
                    />
                  </router-link>
                </span>
              </template>
            </guide-step-popover>
            <!-- 后面的其他 -->
            <span v-else :key="project.id" :style="{ 'margin-left': margin }">
              <router-link :to="`/project/${project.id}`" tag="div">
                <project-card
                  :project="project"
                  :role="1"
                  :page-size="pageSizeInCard"
                  @copyProject="copyProject(project)"
                  @setVisible="setVisible(project)"
                  @deleteProject="deleteProject"
                />
              </router-link>
            </span>
          </template>
          <div
            v-show="loading && !isCreatingNewProject"
            class="loading"
            :style="{ 'margin-left': margin }"
          >
            <a-icon-font type="iconMySQLlianjieceshi" class="add-icon" />
            <br />
          </div>
        </div>
        <!-- 列表模式 -->
        <div
          v-show="!isCard"
          class="projects"
          :style="{ 'max-height': `${height - 216}px` }"
        >
          <a-button class="create-project-button" @click="setAddProjectVisible">
            新建项目
          </a-button>

          <a-table
            class="projects-table"
            :columns="columns"
            :data-source="projects"
            :pagination="false"
            @change="handleTableChange"
          >
            <span slot="name" slot-scope="text, record">
              <router-link :to="`/project/${record.id}`" tag="div">
                <a class="list-item-name" @click="handleClick">{{ text }}</a>
              </router-link>
            </span>
            <span slot="time" slot-scope="text">
              {{
                text.substring(0, text.indexOf('T')) +
                ' ' +
                text.substring(text.indexOf('T') + 1)
              }}
            </span>
            <span slot="id" slot-scope="text, record">
              <router-link :to="`/management/project/${record.id}/details`">
                <a class="list-item">详细信息</a>
              </router-link>
              <a-divider type="vertical" />
              <a class="list-item" @click.stop="copyProject(record)">复制</a>
              <a-divider type="vertical" />
              <a class="list-item" @click.stop="setVisible(record)">删除</a>
              <a-divider type="vertical" />
            </span>
          </a-table>
          <a-pagination
            v-model="currentInList"
            class="table-pagination"
            :total="totalElement"
            show-less-items
            show-size-changer
            show-quick-jumper
            @showSizeChange="onShowSizeChange"
            @change="onPageChange"
          />
        </div>
      </a-tab-pane>
      <a-tab-pane key="参与" tab="我参与的">
        <div v-if="projects.length === 0" class="div-empty">
          <img alt="" src="@/assets/view/dataview-empty.svg" />
          <p>暂无项目</p>
        </div>
        <div v-else>
          <!-- 卡片模式 -->
          <div
            v-show="isCard"
            class="projects projects-card"
            :style="{ 'max-height': `${height - 216}px` }"
          >
            <span
              v-for="project in projectsCard"
              :key="project.id"
              :style="{ 'margin-left': margin }"
            >
              <router-link :to="`/project/${project.id}`" tag="div">
                <project-card :project="project" :role="2" />
              </router-link>
            </span>
            <div
              v-show="loading && !isCreatingNewProject"
              class="loading"
              :style="{ 'margin-left': margin }"
            >
              <a-icon-font type="iconMySQLlianjieceshi" class="add-icon" />
              <br />
            </div>
          </div>
          <!-- 列表模式 -->
          <div
            v-show="!isCard"
            class="projects"
            :style="{ 'max-height': `${height - 216}px` }"
          >
            <a-table
              class="projects-table"
              :columns="columns"
              :data-source="projects"
              :pagination="false"
              @change="handleTableChange"
            >
              <span slot="name" slot-scope="text, record">
                <router-link :to="`/project/${record.id}`" tag="div">
                  <a class="list-item-name" @click="handleClick">{{ text }}</a>
                </router-link>
              </span>
              <span slot="time" slot-scope="text">
                {{
                  text.substring(0, text.indexOf('T')) +
                  ' ' +
                  text.substring(text.indexOf('T') + 1)
                }}
              </span>
              <span slot="id" slot-scope="text, record">
                <router-link :to="`/management/project/${record.id}/details`">
                  <a>详细信息</a>
                </router-link>
                <a-divider type="vertical" />
              </span>
            </a-table>
            <a-pagination
              v-model="currentInList"
              class="table-pagination"
              :total="totalElement"
              show-less-items
              show-size-changer
              show-quick-jumper
              @showSizeChange="onShowSizeChange"
              @change="onPageChange"
            />
          </div>
        </div>
      </a-tab-pane>
      <a-tab-pane key="模板" tab="模板项目">
        <div v-if="projectsCard.length === 0" class="div-empty">
          <img alt="" src="@/assets/view/dataview-empty.svg" />
          <p>暂无项目</p>
        </div>
        <div v-else>
          <!-- 卡片模式 -->
          <div
            v-show="isCard"
            class="projects projects-card"
            :style="{ 'max-height': `${height - 216}px` }"
          >
            <span
              v-for="project in projectsCard"
              :key="project.id"
              :style="{ 'margin-left': margin }"
            >
              <router-link :to="`/project/${project.id}`" tag="div">
                <project-card
                  :project="project"
                  :role="3"
                  @copyProject="copyTemplateProject(project)"
                />
              </router-link>
            </span>
            <div
              v-show="loading && !isCreatingNewProject"
              class="loading"
              :style="{ 'margin-left': margin }"
            >
              <a-icon-font type="iconMySQLlianjieceshi" class="add-icon" />
              <br />
            </div>
          </div>
          <!-- 列表模式 -->
          <div
            v-show="!isCard"
            class="projects"
            :style="{ 'max-height': `${height - 216}px` }"
          >
            <a-table
              class="projects-table"
              :columns="columns"
              :data-source="projects"
              :pagination="false"
              @change="handleTableChange"
            >
              <span slot="name" slot-scope="text, record">
                <router-link :to="`/project/${record.id}`" tag="div">
                  <a class="list-item-name" @click="handleClick">{{ text }}</a>
                </router-link>
              </span>
              <span slot="time" slot-scope="text">
                {{
                  text.substring(0, text.indexOf('T')) +
                  ' ' +
                  text.substring(text.indexOf('T') + 1)
                }}
              </span>
              <span slot="id" slot-scope="text, record">
                <a class="list-item" @click.stop="copyTemplateProject(record)"
                  >复制到我的项目</a
                >
                <a-divider type="vertical" />
              </span>
            </a-table>
            <a-pagination
              v-model="currentInList"
              class="table-pagination"
              :total="totalElement"
              show-less-items
              show-size-changer
              show-quick-jumper
              @showSizeChange="onShowSizeChange"
              @change="onPageChange"
            />
          </div>
        </div>
      </a-tab-pane>
      <a-button slot="tabBarExtraContent" type="link" @click="switchMode">
        <a-icon-font
          v-if="isCard"
          class="mode-icon"
          type="iconliebiaoxianshi"
        />
        <a-icon-font v-else class="mode-icon" type="icontuxianshi" />
      </a-button>
    </a-tabs>

    <a-modal
      title="新建项目"
      :visible="addProjectVisible"
      ok-text="确定"
      cancel-text="取消"
      centered
      @ok.stop="createProject"
      @cancel.stop="cancelCreate"
    >
      <div>
        <p>项目名称：</p>
        <a-input
          id="projectNameInput"
          v-model="projectName"
          placeholder="请输入"
          onfocus="this.select()"
          auto-focus
          @change="showWarning = false"
          @keyup.enter="createProject"
        />
        <p v-show="showWarning" class="warning-text">该项目名称文件夹已存在</p>
        <p class="description-input">项目描述：</p>
        <a-textarea
          v-model="description"
          placeholder="请输入"
          class="projectDesc"
        />
      </div>
    </a-modal>
  </div>
</template>

<script lang="ts">
/**
 * show all projects of current user
 * @author Huihua Lu
 */
import { Component, Vue } from 'vue-property-decorator'
import { Modal } from 'ant-design-vue'
import ProjectCard from '@/components/projects/ProjectCard.vue'
import GuideStepPopover from '@/components/user-guide/GuideStepPopover.vue'
import ProjectStore, { Project } from '@/store/modules/project'
import UserGuideStore from '@/store/modules/user-guide'

@Component({
  components: {
    ProjectCard,
    GuideStepPopover,
  },
})
export default class ProjectView extends Vue {
  private addProjectVisible: boolean = false

  private projectName: string = '未命名项目'
  private description: string = ''
  private showWarning: boolean = false

  public margin = '20px'
  public height = 100
  public modalVisible = false
  public project: any = {}
  public projectCreated: any = {}
  public projectJoined: any = {}
  public projectTemplate: any = {}
  public projectType: string = '创建'
  public projectsCard: any = []
  public isCreatingNewProject: boolean = true

  private columns = [
    {
      title: '项目名称',
      dataIndex: 'name',
      key: 'name',
      scopedSlots: { customRender: 'name' },
      sorter: true,
      width: '33%',
    },
    {
      title: '最近更新',
      dataIndex: 'gmtModify',
      key: 'time',
      scopedSlots: { customRender: 'time' },
      defaultSortOrder: 'descend',
      sorter: true,
      width: '33%',
    },
    {
      title: '操作',
      dataIndex: 'id',
      key: 'id',
      scopedSlots: { customRender: 'id' },
      width: '33%',
    },
  ]

  private currentInCard: number = 1 // 当前页码
  private pageSizeInCard: number = 10 // 每页大小
  private currentInList: number = 1 // 当前页码
  private pageSizeInList: number = 10 // 每页大小
  private sorterOrder: string = 'desc'
  private sorterKey: string = 'gmt_modify'
  // public totalElement: number = 0

  public async created(): Promise<void> {
    this.initViewGuideStep(6)
    this.getMargin()
    this.parseRouterPath()
    ProjectStore.clearActiveProject()
    // const response = await queryAllProjects({data: this.defaultPostData})
    await ProjectStore.loadProjects(
      this.isCard ? this.defaultPostDataInCard : this.defaultPostDataInList
    )
    this.projectsCard = this.projects

    this.handleScroll()
    window.addEventListener('resize', this.handleResize)
    const temporary: any = this.getTabContentEl() // document.querySelector('#projects')
    if (temporary) {
      temporary.addEventListener('scroll', this.handleScroll)
    }
  }

  /**
   * 进入页面初始化引导步骤， 当上一步是 step-5
   */
  public initViewGuideStep(step: number) {
    if (UserGuideStore.currentStep === 5) {
      UserGuideStore.toSpecifiedGuideStep(step)
    }
  }

  /**
   * 更新新用户引导步骤
   */
  public updateGuideStep(step: number) {
    UserGuideStore.toSpecifiedGuideStep(step)
  }

  /**
   * 修改当前步骤的状态 true 正在进行中
   */
  public setGuideStepOnGoing(type: boolean) {
    UserGuideStore.setCurrentGuideStepInProgress(type)
  }

  public get totalElement() {
    return ProjectStore.totalElements
  }

  public get projects(): any[] {
    const myProjects: any[] = []
    ProjectStore.projects.forEach((item, index) => {
      myProjects.push({
        key: index,
        ...item,
      })
    })
    return myProjects
  }

  /**
   * 解析路由路径参数
   */
  public parseRouterPath() {
    const { path } = this.$route
    if (path.includes('/cooperate')) {
      this.projectType = '参与'
    } else if (path.includes('/template')) {
      this.projectType = '模板'
    }
  }

  public getTabContentEl() {
    const targetTab = this.$el.querySelector('.project-content')
    const targetElement = targetTab?.querySelector('.projects.projects-card')
    return targetElement
  }

  public async onPageChange(page: any, size: any) {
    this.currentInList = page
    this.pageSizeInList = size
    await ProjectStore.loadProjects(
      this.isCard ? this.defaultPostDataInCard : this.defaultPostDataInList
    )
  }
  public async onShowSizeChange(page: any, size: any) {
    this.currentInList = page
    this.pageSizeInList = size
    await ProjectStore.loadProjects(
      this.isCard ? this.defaultPostDataInCard : this.defaultPostDataInList
    )
  }

  public async handleTableChange(pagination: any, filters: any, sorter: any) {
    console.log(pagination, filters, sorter)
    if (sorter.order) {
      this.sorterKey =
        sorter.field === 'gmtModify' ? 'gmt_modify' : sorter.field
      this.sorterOrder = sorter.order === 'descend' ? 'desc' : 'asc'
    } else {
      this.sorterKey = 'gmt_modify'
      this.sorterOrder = 'desc'
    }

    await ProjectStore.loadProjects(this.defaultPostDataInList)
  }

  public async handleTabChange() {
    this.currentInCard = 1
    this.currentInList = 1

    let path = ''
    switch (this.projectType) {
      case '创建':
        path = '/management/projects'
        break
      case '参与':
        path = '/management/projects/cooperate'
        break
      case '模板':
        path = '/management/projects/template'
        break
      default:
        break
    }
    this.$router.push(path)

    ProjectStore.clearState()
    this.projectsCard = []
    await ProjectStore.loadProjects(
      this.isCard ? this.defaultPostDataInCard : this.defaultPostDataInList
    )
    this.projectsCard = this.projects

    if (this.isCard) {
      this.handleScroll()
      const elements: any = document.querySelectorAll('.projects.projects-card')
      elements.forEach((ele: any) =>
        ele.removeEventListener('scroll', this.handleScroll)
      ) // 去除所有监听的scroll事件
      const temporary: any = this.getTabContentEl() // document.querySelector('#projects')
      if (temporary) {
        temporary.addEventListener('scroll', this.handleScroll)
      }
    }
  }

  public destroyed() {
    window.removeEventListener('resize', this.handleResize)
  }

  public getMargin() {
    // 获取高度
    this.height = document.body.clientHeight
    // 当前屏幕长宽
    const { clientWidth } = document.body
    // 最小间隙
    const minMargin = 20
    const cols = Math.floor((clientWidth - minMargin - 64) / (250 + minMargin))
    // 获取margin
    this.margin = `${Math.floor(
      (clientWidth - cols * 250 - 64) / (cols + 1)
    )}px`
  }

  public handleResize() {
    this.getMargin()
    if (this.isCard) {
      this.handleScroll()
    }
  }
  public get loading() {
    if (this.pageSizeInCard * this.currentInCard >= this.totalElement) {
      return false
    }
    return true
  }

  public get isCard(): boolean {
    return ProjectStore.isCardMode
  }
  public get defaultPostDataInCard(): any {
    const postData = {
      pageNum: this.currentInCard,
      pageSize: this.pageSizeInCard,
      projectType:
        this.projectType === '创建' ? 0 : this.projectType === '参与' ? 2 : 1,
      sortColumn: 'gmt_modify',
      sortMethod: 'desc',
    }
    return postData
  }

  public get defaultPostDataInList(): any {
    const postData = {
      pageNum: this.currentInList,
      pageSize: this.pageSizeInList,
      projectType:
        this.projectType === '创建' ? 0 : this.projectType === '参与' ? 2 : 1,
      sortColumn: this.sorterKey,
      sortMethod: this.sorterOrder,
    }
    return postData
  }

  public async handleScroll() {
    if (this.isCard) {
      // 当前屏幕长宽
      const { clientWidth } = document.body
      // 最小间隙
      const minMargin = 20
      const cols = Math.floor(
        (clientWidth - minMargin - 64) / (250 + minMargin)
      )

      const { scrollTop }: any = this.getTabContentEl() // document.querySelector('#projects') // 滚动条距离顶部的高度
      const scrollHeight =
        (((this.pageSizeInCard * this.currentInCard <= this.totalElement
          ? this.pageSizeInCard * this.currentInCard
          : this.totalElement) +
          2) /
          cols) *
        165 // 当前页面的总高度
      const clientHeight: any = document.body.clientHeight - 260 // 当前可视的页面高度
      const totalHeight = clientHeight + scrollTop

      if (scrollHeight - totalHeight < 40 && this.loading) {
        // 注：-40 上拉加载更灵敏
        this.currentInCard += 1
        // 加载数据
        // postData.pageSize = this.pageSize
        await ProjectStore.loadProjects(
          this.isCard ? this.defaultPostDataInCard : this.defaultPostDataInList
        )
        this.projectsCard = this.projectsCard.concat(this.projects)
        console.log(this.projectsCard)
        this.handleScroll()
      }
    }
  }

  /**
   * 点击新建项目
   */
  public setAddProjectVisible() {
    this.setGuideStepOnGoing(true)
    this.isCreatingNewProject = true
    this.addProjectVisible = true
    this.$nextTick(() => {
      const projectNameInput: any = document.querySelector('#projectNameInput')
      projectNameInput.focus()
    })
  }

  public cancelCreate() {
    this.setGuideStepOnGoing(false)
    this.addProjectVisible = false
    this.isCreatingNewProject = false
  }

  public changeProjectName(value: string) {
    this.projectName = value
  }

  public changeDescription(value: string) {
    this.description = value
  }

  /* 创建项目 */
  public async createProject() {
    if (!this.projectName.trim()) {
      this.$message.error('项目名不能为空')
      return
    }
    const passData = {
      name: this.projectName.trim(),
      description: this.description,
    }
    // if (this.isCard) {
    //   this.currentInCard = 1
    // }
    await ProjectStore.createNewProject({
      data: passData,
      queryData: this.isCard
        ? this.defaultPostDataInCard
        : this.defaultPostDataInList,
    })
      .then(async () => {
        // ToDo 优化
        if (this.isCard) {
          this.currentInCard = 1
        }
        await ProjectStore.loadProjects(
          this.isCard ? this.defaultPostDataInCard : this.defaultPostDataInList
        )
        this.addProjectVisible = false
        this.description = ''
        this.projectName = '未命名项目'
        if (this.isCard) {
          this.projectsCard = this.projects
          this.handleScroll()
          this.isCreatingNewProject = false
        }
        // 更新用户引导步骤
        this.updateGuideStep(7)
      })
      .catch(() => {
        this.showWarning = true
      })
  }

  public async switchMode() {
    ProjectStore.setIsCardMode(!this.isCard)
    if (ProjectStore.isCardMode) {
      this.projectsCard = []
      this.currentInCard = 1
      this.pageSizeInCard = 10
      await ProjectStore.loadProjects(this.defaultPostDataInCard)
      this.projectsCard = this.projects
      this.handleScroll()
    } else {
      this.currentInList = 1
      this.pageSizeInList = 10
      await ProjectStore.loadProjects(this.defaultPostDataInList)
    }
  }

  /* 删除项目时弹窗确认 */
  public setVisible(project: Project): void {
    // this.modalVisible = true
    this.project = project
    Modal.confirm({
      title: '确定删除该项目么？',
      class: 'delete-project-modal',
      onOk: this.deleteProject,
      okText: '确定',
      cancelText: '取消',
      maskClosable: true,
    })
  }

  /* 复制项目 */
  public async copyProject(project: Project): Promise<void> {
    this.project = project
    if (this.isCard) {
      this.currentInCard = 1
    }
    await ProjectStore.copyProject({
      projectId: this.project.id,
      queryData: this.isCard
        ? this.defaultPostDataInCard
        : this.defaultPostDataInList,
    })
      .then(() => {
        if (this.isCard) {
          this.projectsCard = this.projects
          this.handleScroll()
        }
      })
      .catch(() => {
        this.showWarning = true
      })
  }

  /* 复制模板项目 */
  public async copyTemplateProject(project: Project): Promise<void> {
    this.project = project
    if (this.isCard) {
      this.currentInCard = 1
    }
    await ProjectStore.copyTemplateProject({
      projectId: this.project.id,
      queryData: this.isCard
        ? this.defaultPostDataInCard
        : this.defaultPostDataInList,
    })
      .then(() => {
        if (this.isCard) {
          this.projectsCard = this.projects
          this.handleScroll()
        }
      })
      .catch(() => {
        this.showWarning = true
      })
  }

  /* 删除项目 */
  public async deleteProject(): Promise<void> {
    this.modalVisible = false
    if (this.isCard) {
      this.currentInCard = 1
    }
    await ProjectStore.deleteProject({
      projectId: this.project.id,
      queryData: this.isCard
        ? this.defaultPostDataInCard
        : this.defaultPostDataInList,
    })
      .then(() => {
        if (this.isCard) {
          this.projectsCard = this.projects
          this.handleScroll()
        }
      })
      .catch(() => {
        this.showWarning = true
      })
  }

  /* 取消删除 */
  public handleCancel(): void {
    this.modalVisible = false
  }

  /* 点击某个项目时将该项目设为activeProject */
  public handleClick(): void {
    ProjectStore.setActiveProject(this.project)
  }
}
</script>

<style lang="less">
@import '@/constants';

.projects {
  align-items: flex-start;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  overflow-y: auto;

  &::-webkit-scrollbar {
    height: 6px;
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: rgba(144, 147, 153, 0.5);
    border-radius: 6px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 5px;
  }
}

.project-content {
  background: #fff;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 1px;
  line-height: 20px;
  margin: 16px;
  padding: 20px;
  padding-top: 10px;
}

.add-icon {
  color: #9b9da8;
  font-size: 3rem;
  margin-top: 49px;
}

.add-project {
  color: @TEXT_COLOR;
  font-size: @TEXT_FONT_SIZE_BIG;
}

.card {
  background-color: @PROJECT_CARD_COLOR;
  border: 1px solid #e3e3e7;
  border-radius: 5px;
  cursor: pointer;
  height: @PROJECT_CARD_HEIGHT;
  margin: 20px 0;
  text-align: center;
  width: @PROJECT_CARD_WIDTH;

  .project-name {
    color: @TEXT_COLOR;
    font-size: @TEXT_FONT_SIZE_BIG;
    font-weight: bold;
    position: relative;
    text-align: center;
    top: 66px;
    width: 100%;
  }

  &:hover {
    background-color: rgba(105, 115, 255, 0.08);
    box-shadow: 0 0 17px -7px #6973ffba;

    .project-name {
      visibility: visible;
    }
  }
}

.projects .loading {
  background-color: @PROJECT_CARD_COLOR;
  font-size: 14px;
  height: @PROJECT_CARD_HEIGHT;
  margin: 20px 0;
  text-align: center;
  width: @PROJECT_CARD_WIDTH;
}

.div-empty {
  align-items: center;
  justify-content: center;
  margin-top: calc(30vh);
  // display: flex;
  min-height: 100%;
  text-align: center;
}

.description-input {
  margin-top: 50px;
}

.warning-text {
  color: #e6505a;
  display: inline-block;
  margin: 0;
}

.create-project-button {
  background: #6973ff;
  color: #fff;
  height: 32px;
  margin-bottom: 14px;
  width: 88px;
}

.projects-table {
  width: 100%;
}

.table-pagination {
  padding: 20px;
  text-align: right;
  width: 100%;
}

.mode-icon {
  color: #6973ff;
  height: 19px;
  width: 19px;
}

.list-item:hover {
  font-weight: 600;
}

.list-item-name {
  color: #6973ff;
  transition: color 0s;
}

.list-item-name:hover {
  color: #6973ff;
  font-weight: 600;
}

.projectDesc {
  height: 120px;
  resize: none;
}
</style>
